package cn.yunyichina.provider.merchant.service.impl;

import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.impl.YytServiceImpl;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.merchant.BusinessCallRequestDto;
import cn.yunyichina.provider.iface.entity.merchant.NotifyMessageRequestDto;
import cn.yunyichina.provider.iface.service.IMerchant;
import cn.yunyichina.provider.merchant.entity.MerchantConfig;
import cn.yunyichina.provider.merchant.entity.MerchantMessage;
import cn.yunyichina.provider.merchant.entity.MethodRouter;
import cn.yunyichina.provider.merchant.pool.WorkerThreadPool;
import cn.yunyichina.provider.merchant.thread.SaveMessageThread;
import cn.yunyichina.provider.merchant.util.DataUtil;
import cn.yunyichina.utils.commons.StringUtils;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogScene;
import com.alibaba.fastjson.JSON;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by kevin on 2017/12/6.
 */
public class MerchantServiceImpl extends YytServiceImpl implements IMerchant{

    @Override
    public String getErrorCode() {
        return "25000";
    }

    /**
     * 消息通知类接口
     * @param notifyMessageRequestDto
     * @return
     */
    @Override
    public ResCommon<Void> notifyMessage(NotifyMessageRequestDto notifyMessageRequestDto) {
        ResCommon<Void> resCommon=new ResCommon<>("0","sucessful");

        if(StringUtils.isBlank(notifyMessageRequestDto.getOrgCode())||
                StringUtils.isBlank(notifyMessageRequestDto.getOrgName())||
                StringUtils.isBlank(notifyMessageRequestDto.getOrderNo())||
                StringUtils.isBlank(notifyMessageRequestDto.getMessageContent())){
            resCommon.setResultCodeAndMessage("25001","参数不能为空");
            return resCommon;
        }

        if(notifyMessageRequestDto.getNotifyScene()==null){
            resCommon.setResultCodeAndMessage("25001","通知场景不能为空");
            return resCommon;
        }

        WorkerThreadPool.execute(new SaveMessageThread(notifyMessageRequestDto));
        return resCommon;
    }

    /**
     * 业务调用类接口
     * @param businessCallRequestDto
     * @return
     */
    @Override
    public Response businessCall(BusinessCallRequestDto businessCallRequestDto) {
        Response response = new Response("0","sucessful");

        if(StringUtils.isBlank(businessCallRequestDto.getOrgCode())||
                StringUtils.isBlank(businessCallRequestDto.getOrgName())||
                StringUtils.isBlank(businessCallRequestDto.getOrderNo())||
                StringUtils.isBlank(businessCallRequestDto.getBusinessContent())){
            response.setResultCodeAndMessage("25001","参数不能为空");
            return response;
        }

        if(businessCallRequestDto.getNotifyScene() == null){
            response.setResultCodeAndMessage("25001","场景号不能为空");
            return response;
        }

        //取出所有方法路由
        Map<String, MethodRouter> methodRouterMap = DataUtil.getAllMethodRouters();

        String notifyScene = businessCallRequestDto.getNotifyScene().getCode();
        String method = DataUtil.getMethdFromEnum(notifyScene);
        String key = businessCallRequestDto.getOrgCode()+"_" + method;
        String handleMessage = "";
        if(!methodRouterMap.containsKey(key)){
            handleMessage = "该场景对应方法路由在表method_router未配置[key:" + key + "]!";
            Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, businessCallRequestDto.getOrderNo(), handleMessage);
            response.setResultCodeAndMessage("25001", handleMessage);
            return response;
        }
        MethodRouter methodRouter = methodRouterMap.get(key);


        //取出所有公司配置
        Map<String, MerchantConfig> merchantConfigMap = DataUtil.getAllMerchantConfig();
        MerchantConfig merchantConfig = merchantConfigMap.get(businessCallRequestDto.getOrgCode());
        Object owner = SpringContextHandler.getBean(methodRouter.getServiceImpl());
        if(owner == null){
            handleMessage = "该场景对应的服务并未实现[serviceimpl:" + methodRouter.getServiceImpl() + "]!";
            Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, businessCallRequestDto.getOrderNo(), handleMessage);
            response.setResultCodeAndMessage("25001", handleMessage);
            return response;
        }

        String methodInvoke = methodRouter.getInvokeMethod();
        Method targetMethod;
        try {
            targetMethod = owner.getClass().getDeclaredMethod(methodInvoke, MerchantConfig.class, MethodRouter.class, BusinessCallRequestDto.class);
        } catch (NoSuchMethodException e) {
            handleMessage="该通知场景对应的服务,并未实现对应的3个入参为String的方法[serviceimpl:" + methodRouter.getServiceImpl() +
                    ",method:" + methodInvoke + "]!";
            Log.e(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, businessCallRequestDto.getOrderNo(), handleMessage);
            response.setResultCodeAndMessage("25001", handleMessage);
            return response;
        }

        try {
            response = (Response) targetMethod.invoke(owner,new Object[]{merchantConfig, methodRouter, businessCallRequestDto});
            Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, businessCallRequestDto.getOrderNo(), "调用后结果:"+ JSON.toJSONString(response));
        } catch (Exception e) {
            handleMessage="该场景对应的服务,调用出错[serviceimpl:" + methodRouter.getServiceImpl() +
                    ",method:" + methodInvoke + "]!";
            Log.e(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, businessCallRequestDto.getOrderNo(), handleMessage, e);
        }

        return response;
    }
}
